//
//  NSObject+HCTB.h
//  HCToolBox
//
//  Created by Hotacool on 2019/3/19.
//  NSObject类的扩展方法库

#import <Foundation/Foundation.h>
/// 内存管理策略
typedef NS_ENUM(NSUInteger, HCMemoryPolicy) {
    HCMemoryPolicyAssign = 0,
    HCMemoryPolicyRetain,
    HCMemoryPolicyCopy,
};

/// 对象属性信息
typedef struct {
    BOOL readonly;
    BOOL nonatomic;
    BOOL weak;
    BOOL canBeCollected;
    BOOL dynamic;
    HCMemoryPolicy memoryManagementPolicy;// 内存管理策略
    SEL _Nullable getter;
    SEL _Nullable setter;
    const char * _Nullable ivar;
    char * _Nullable typeEncode;//非对象类型encode type
    Class _Nullable objectClass;//对象类型
    char type[];
} HCPropertyAttributes;

NS_ASSUME_NONNULL_BEGIN

@interface NSObject (HCTB)

#pragma mark runtime extensions
/// swizzling类的实例方法：将原类的实例方法，替换为目标类的方法实现。
/// @param fromClass 原始类名
/// @param originSelector 原始方法
/// @param toClass 目标类名
/// @param newSelector 目标方法
+ (BOOL)swizzleMethodsFrom:(Class)fromClass
                     selector:(SEL)originSelector
                           to:(Class)toClass
                  newSelector:(SEL)newSelector;

/// 获取property属性修饰信息
/// @param propertyName 属性名
+ (HCPropertyAttributes *)getPropertyAttributes:(char *)propertyName withCLass:(Class)cls ;
#pragma mark 为实例对象添加associate对象的相关操作。

/// 添加associate对象，属性默认为strongly
/// @param object 添加对象
/// @param key key
- (void)hctb_setObject:(nullable id)object forKey:(NSString*)key;

/// 添加weakly属性对象
/// @param object 添加对象
/// @param key key
- (void)hctb_setObjectWeakly:(nullable id)object forKey:(NSString*)key;

/// 获取对应key的对象
/// @param key key
- (id)hctb_objectForKey:(NSString*)key;

/// 清除所有associate对象
- (void)hctb_removeAllObjects;

/// 获取所有associate对象的key
- (NSArray*)hctb_allKeys;

#pragma mark objective-c category extension
/// 为object添加动态property
/// @param propertyName 属性名
+ (BOOL)addDynamicProperty:(char *_Nullable)propertyName toClass:(Class)cls ;
@end

NS_ASSUME_NONNULL_END
